import React, {useCallback, useEffect, useRef, useState} from "react"
import {
    addProcurementReturnItem,
    AddProcurementReturnItemRequest,
    deleteProcurementReturnItem,
    deleteProcurementReturnItemSub,
    findAllGoodsWithHistoryProcurementReturnSupplier,
    getProcurementReturnDetail,
    ProcurementReturnDetail,
    ProcurementReturnItem,
    // receiptProcurementReturn,
    submitProcurementReturn,
    updateProcurementReturnItemAmount, updateProcurementReturnItemNote,
    updateProcurementReturnItemPrice,
    updateProcurementReturnItemSubNote,
    updateProcurementReturnItemSubPrice
} from "../../apis/ProcurementReturnApi";
import {Button, Col, Descriptions, Input, Row, Space, Table, theme, Typography} from "antd";
import {OffsetDateTime} from "@js-joda/core";
import {convertAntdTableToExcel, ExportedColumnProps} from "../../utils/AntdTableUtils";
import AuthorizationResource from "../../components/AuthorizationResource";
import {DeleteOutlined, EditOutlined} from "@ant-design/icons";
import DataPageLayout from "../../components/DataPageLayout";
import ArrayUtils from "@zxy-cn/array-utils";
import dashboardPageStore from "../../store/DashboardPageStore";
import {observerDashboardPageWrapper} from "./ObserverDashboardPageWrapper";
import employeeAuthorizationStore from "../../store/EmployeeAuthorizationStore";
import LoadableButton from "../../components/LoadableButton";
import {useNavigate} from "react-router";
import {Link} from "react-router-dom";
import EditOrderItemRow, {EditOrderItemGoodsData} from "../../components/EditOrderItemRow";
import {saveWorkbookTo} from "../../utils/FileSaver";
import GoodsTable from "../../components/GoodsTable";
import EditAmountAndUnitPopover from "../EditAmountAndUnitPopover";
import {useLiveQuery} from "dexie-react-hooks";
import {GoodsAmountAndUnitUseHistoryScope, myDatabase} from "../../database/MyDatabase";
import {DATE_WITH_TIME_FORMATER} from "../../utils/Date";
import {updateMarketOrderItemSubAmount} from "../../apis/MarketOrderApi";
import SingleInputPopover from "../SingleInputPopover";
import {
    updateProcurementItemNote,
    updateProcurementItemPurchasePrice,
    updateProcurementItemSubNote,
    updateProcurementItemSubPurchasePrice, updateProcurementNote
} from "../../apis/ProcurementApi";
import {useSubGoodsTableColumnConfiguration} from "../../utils/SubGoodsHooks";


export interface pageProps {
    id: number
}

const myPath = "procurementReturns/{id}"

const ProcurementReturnDetailPage: React.FC<pageProps> = ({id}) => {
    const [loading, setLoading] = useState(false)
    const [data, setData] = useState<ProcurementReturnDetail>()
    const query = useCallback(() => {
        setLoading(true)
        getProcurementReturnDetail(id).then(response => {
            dashboardPageStore.setTitle(myPath.replace("{id}", id.toString()), response.data.supplier.name + "采购退货单")
            setData(response.data)
        }).finally(() => {
            setLoading(false)
        })
    }, [id])

    useEffect(() => {
        query()
    }, [query]);

    let token = theme.useToken();

    let navigate = useNavigate();
    let columnsRef = useRef<ExportedColumnProps<ProcurementReturnItem>[]>();

    let amountAndUnitHistories = useLiveQuery(() => {
        return myDatabase.goodsAmountAndUnitUseHistory.where({
            scope: GoodsAmountAndUnitUseHistoryScope.PROCUREMENT_RETURN,
            resourceId: id,
        }).toArray()
    }, [id]);

    let subGoodsTableColumnConfiguration = useSubGoodsTableColumnConfiguration<ProcurementReturnItem>();
    return (
        <>
            {!loading ? <Descriptions title={"订单明细"}>
                <Descriptions.Item label={"供货商"}>{data?.supplier?.name}</Descriptions.Item>
                <Descriptions.Item label={"创建人"}>{data?.createdBy?.name}</Descriptions.Item>
                {!!data?.submittedDateTime && <Descriptions.Item
                    label={"创建时间"}>{data?.submittedDateTime.format(DATE_WITH_TIME_FORMATER)}</Descriptions.Item>}
                {!!data?.receiptDateTime ? <Descriptions.Item
                    label={"入库时间"}>{data.receiptDateTime.format(DATE_WITH_TIME_FORMATER)}</Descriptions.Item> : undefined}

            </Descriptions> : null}
            <Row gutter={8} style={{margin: "12px 0"}}>
                <Col>
                    <LoadableButton onClick={async (event) => {
                        event.stopPropagation()
                        let workbook = await convertAntdTableToExcel(columnsRef.current!!, data?.items ?? [], ["条码", "名称", "数量", "零售价"]);
                        await saveWorkbookTo(workbook, `${data?.supplier?.name}采购退货单-${data?.submittedDateTime ?? data!.createdDateTime.format(DATE_WITH_TIME_FORMATER)}`)
                    }}>
                        导出
                    </LoadableButton>
                </Col>
                <Col>
                    <LoadableButton onClick={async (event) => {
                        event.stopPropagation()

                    }}>导入</LoadableButton>
                </Col>
                {/*{employeeAuthorizationStore.hasAuthority("采购_入库_入库")*/}
                {/*&& !data?.receiptDateTime*/}
                {/*&& !!data?.submittedDateTime ?*/}
                {/*    <Col>*/}
                {/*        <LoadableButton onClick={async (event) => {*/}
                {/*            event.stopPropagation()*/}
                {/*            let receiptId = (await receiptProcurementReturn(id)).data;*/}
                {/*            setData({...data!, receiptDateTime: OffsetDateTime.now()})*/}
                {/*            navigate(`/procurementReturns/receipts/${receiptId}`)*/}
                {/*        }}>入库</LoadableButton>*/}
                {/*    </Col> : undefined}*/}
                {employeeAuthorizationStore.hasAuthority("采购_退货_创建") && !data?.submittedDateTime &&
                    <Col>
                        <LoadableButton onClick={async (event) => {
                            event.stopPropagation()
                            await submitProcurementReturn(id)
                            setData({...data!, submittedDateTime: OffsetDateTime.now()})
                        }}>
                            提交退货单
                        </LoadableButton>
                    </Col>}
                {<Col>
                    <LoadableButton onClick={async (event) => {
                        // await submitProcurementReturn(id)
                        // setData({...data!, submittedDateTime: OffsetDateTime.now()})
                    }}>
                        打印
                    </LoadableButton></Col>}
                <div style={{flexGrow: 1}}/>
                {employeeAuthorizationStore.hasAuthority("采购_退货_查询") && !!data?.receiptDateTime &&
                    <Link to={`/procurementReturns/receipts/${data?.receiptId}`}>
                        <Button type={"link"}>查看入库单</Button>
                    </Link>}
            </Row>

            {!!data && ((employeeAuthorizationStore.hasAuthority("采购_退货_修改") && !data?.submittedDateTime) && !data?.receiptDateTime) &&
                <EditOrderItemRow<EditOrderItemGoodsData & {
                    price: number
                }>
                    request={{}}
                    withAmount
                    withPrice
                    fetchGoods={async () => {
                        let response = await findAllGoodsWithHistoryProcurementReturnSupplier(data!!.supplier.id);
                        return response.data.map(it => {
                            return {
                                ...it,
                                units: [],
                            }
                        })
                    }}
                    optionRender={it => {
                        return <Space>
                            <span>{it.subGoods ? `${it.barcode}|${it.subGoods.number}` : it.barcode}</span>
                            <span>{it.subGoods ? it.subGoods.name + `（${it.name}）` : it.name}</span>
                            <span>￥{it.price}</span>
                        </Space>
                            ;
                    }}
                    onFinish={async (values) => {
                        let existed = amountAndUnitHistories?.find(it => it.goodsId === values.goodsId);
                        if (existed) {
                            myDatabase.goodsAmountAndUnitUseHistory.delete(existed.id!!)
                        }
                        myDatabase.goodsAmountAndUnitUseHistory.add({
                            scope: GoodsAmountAndUnitUseHistoryScope.PROCUREMENT_RETURN,
                            resourceId: id,
                            amount: values.amount,
                            unitId: values.unitId,
                            goodsId: values.goodsId,
                            price: values.price,
                        })

                        return addProcurementReturnItem(id, {...values, purchasePrice: values.price ?? 0}).then(() => {
                            query()
                        })
                    }}
                    availableAmountAndUnitHistories={amountAndUnitHistories}
                    existedGoodsKeys={data?.items?.map(it => ({goodsId: it.id, subGoodsId: it.subGoods?.id,})) ?? []}/>}
            <DataPageLayout leftActions={<>
            </>}>

                <GoodsTable<ProcurementReturnItem> loading={loading}
                                                   size={"small"}
                                                   customColumns={columns => {
                                                       subGoodsTableColumnConfiguration(columns)
                                                       ArrayUtils.insertAfter(columns, value => value.dataIndex === "name", {
                                                           dataIndex: "amountInOrder",
                                                           title: "数量",
                                                           render: (value, record) => {
                                                               return <div>{value}{record.unit?.name}</div>
                                                           },
                                                           generateExcelValue: (value, record) => {
                                                               return `${value}${record.unit?.name ?? ""}`
                                                           }
                                                       },)
                                                       ArrayUtils.insertAfter(columns, value => value.dataIndex === "price", {
                                                           dataIndex: "returnPrice",
                                                           title: "退货价",
                                                       },)
                                                       columns.push({
                                                           dataIndex: "note",
                                                           title: "备注",
                                                       })
                                                       columns.push({
                                                           ignoreInExcel: true,
                                                           title: "操作",
                                                           render: (_, item, index) => {
                                                               return <>
                                                                   {employeeAuthorizationStore.hasAuthority("采购_退货_修改") && !data?.receiptDateTime &&
                                                                       <EditAmountAndUnitPopover units={[]}
                                                                                                 initialData={{
                                                                                                     amount: item.amountInOrder,
                                                                                                     unitId: item.unit?.id,
                                                                                                     price: item.returnPrice,
                                                                                                 }}
                                                                                                 onConfirm={async value => {
                                                                                                     if (item.subGoods) {
                                                                                                         await updateMarketOrderItemSubAmount(id, item.id, value, item.subGoods.id)
                                                                                                     } else {
                                                                                                         await updateProcurementReturnItemAmount(id, item.id, value)
                                                                                                     }
                                                                                                     let items = Array.from(data?.items ?? []);
                                                                                                     items[index].amountInOrder = value.amount
                                                                                                     setData({
                                                                                                         ...data!,
                                                                                                         items
                                                                                                     })
                                                                                                 }}
                                                                       >
                                                                           <Button type={"link"}
                                                                                   onClick={event => event.stopPropagation()}>修改数量</Button>
                                                                       </EditAmountAndUnitPopover>}
                                                                   {employeeAuthorizationStore.hasAuthority("采购_退货_修改") &&
                                                                       <SingleInputPopover
                                                                           required
                                                                           initialValue={item.returnPrice.toString()}
                                                                           title={"修改退货价"}
                                                                           customInput={(props, ref) => {
                                                                               return <Input ref={ref}
                                                                                             step={0.01}
                                                                                             type={"number"} {...props}/>
                                                                           }}
                                                                           onConfirm={async value => {
                                                                               const number = parseFloat(value)
                                                                               if (item.subGoods) {
                                                                                   await updateProcurementReturnItemSubPrice(id, item.id, number, item.subGoods.id)
                                                                               } else {
                                                                                   await updateProcurementReturnItemPrice(id, item.id, number)
                                                                               }
                                                                               const index = data!.items.indexOf(item)
                                                                               let items = Array.from(data!.items ?? []);
                                                                               items[index].returnPrice = number
                                                                               setData({
                                                                                   ...data!,
                                                                                   items,
                                                                               })
                                                                           }}
                                                                           fieldName={"退货价"}>

                                                                           <Button type={"link"}
                                                                                   onClick={(event) => {
                                                                                       event.stopPropagation()
                                                                                   }}><EditOutlined/>修改采购价</Button>
                                                                       </SingleInputPopover>}
                                                                   {employeeAuthorizationStore.hasAuthority("采购_退货_修改") &&
                                                                       <SingleInputPopover initialValue={item.note}
                                                                                           title={"修改备注"}

                                                                                           onConfirm={async value => {
                                                                                               if (item.subGoods) {
                                                                                                   await updateProcurementReturnItemSubNote(id, item.id, value, item.subGoods.id)
                                                                                               } else {
                                                                                                   await updateProcurementReturnItemNote(id, item.id, value)
                                                                                               }
                                                                                               const index = data!.items.indexOf(item)
                                                                                               let items = Array.from(data!.items ?? []);
                                                                                               items[index].note = value
                                                                                               setData({
                                                                                                   ...data!,
                                                                                                   items,
                                                                                               })
                                                                                           }}
                                                                                           fieldName={"备注"}>

                                                                           <Button type={"link"}
                                                                                   onClick={(event) => {
                                                                                       event.stopPropagation()
                                                                                   }}><EditOutlined/>备注</Button>
                                                                       </SingleInputPopover>}

                                                                   <AuthorizationResource
                                                                       authorities={["采购_退货_修改"]}>
                                                                       <Button type={"link"}
                                                                               danger
                                                                               onClick={async (event) => {
                                                                                   event.stopPropagation()
                                                                                   if (item.subGoods) {
                                                                                       await deleteProcurementReturnItemSub(id, item.id, item.subGoods.id)
                                                                                   } else {
                                                                                       await deleteProcurementReturnItem(id, item.id)
                                                                                   }
                                                                                   let items = Array.from(data!.items);
                                                                                   ArrayUtils.remove(items, item)
                                                                                   setData({
                                                                                       ...data!,
                                                                                       items
                                                                                   })
                                                                               }}>
                                                                           <DeleteOutlined/>
                                                                           删除
                                                                       </Button>
                                                                   </AuthorizationResource>
                                                               </>
                                                           }

                                                       },);
                                                       columnsRef.current = columns;
                                                       return columns;
                                                   }}
                                                   rowKey={(record, index) => {
                                                       return record.id.toString() + (record.subGoods?.id ?? "")
                                                   }} data={data?.items ?? []}
                                                   summary={_ => <Table.Summary.Row>
                                                       <Table.Summary.Cell index={0}>总零售金额</Table.Summary.Cell>
                                                       <Table.Summary.Cell
                                                           index={1}>{ArrayUtils.sum(data?.items?.map(it => it.amountInOrder * it.price) ?? []).toFixed(2)}</Table.Summary.Cell>
                                                       <Table.Summary.Cell index={2}>总退货金额</Table.Summary.Cell>
                                                       <Table.Summary.Cell
                                                           index={3}>{ArrayUtils.sum(data?.items?.map(it => it.amountInOrder * it.returnPrice) ?? []).toFixed(2)}</Table.Summary.Cell>
                                                   </Table.Summary.Row>}
                >
                </GoodsTable>
            </DataPageLayout>

        </>
    )
}

export default observerDashboardPageWrapper(ProcurementReturnDetailPage, myPath, "采购单详情")

